﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace CallTimingAnalysis
{
    public partial class tuBiao : Form
    {
        public tuBiao()
        {
            InitializeComponent();

        }
        private void tuBiao_Load(object sender, EventArgs e)
        {
            this.AutoScroll = true;
            //this.chart1.Height = 600;
            //this.chart1.Width = 4000;
            this.chart1.Dock = DockStyle.Fill;
        }

        public List<LogEntity> logsEntity_pub { get; set; }
        public string FileName { get; set; }
        void ChageText(string str)
        {
            if (this.InvokeRequired)
                this.Invoke(new Action(() => { this.Text = str; }));
            else
                this.Text = str;
        }
        void Inv(Action action)
        {
            if (this.InvokeRequired)
                this.Invoke(action);
            else
                action();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Task.Factory.StartNew(Run);
        }

        private void Run()
        {
            try
            {
                this.ChageText("开始生成图表11111.。。。。。。。。。。。。。。。。。开始分组处理");
                Stopwatch sw = new Stopwatch();
                sw.Start();
                var logsEntity = logsEntity_pub
                    .AsParallel()
                    .GroupBy(p => p.PageName)
                    .ToList()
                    ;

               
                #region title
                this.Inv(new Action(() =>
                {
                    this.chart1.Titles.Add(FileName + ",总请求次数," + logsEntity_pub.Count);
                }));
                this.ChageText("开始生成图表11111.。。。。。。。。。。。。。。。。。Top 3");
                var title2 = "";
                var page_count = logsEntity

                      .Select(p => new  { key = p.Key, c = p.Count() })
                      .OrderByDescending(p => p.c);
                var ti = 0;
                page_count.Take(9).ToList().ForEach(p =>
                {
                    ++ti;
                    if (ti % 3 == 0)
                        title2 += Environment.NewLine;
                    title2 += p.key + ":" + p.c + ";";
                });
                this.Inv(new Action(() =>
                {
                    this.chart1.Titles.Add(title2);
                }));
                this.ChageText("开始生成图表11111.。。。。。。title success---area");

                #endregion
                #region area1
                var area = new System.Windows.Forms.DataVisualization.Charting.ChartArea()
                {
                    Name = "s1",
                };
                area.AxisX.Interval = 1;
                area.AxisX.LineWidth = 1;
                area.AxisY.LineWidth = 1;
                area.AxisX.MajorGrid.Enabled = false;
                area.AxisY.MajorGrid.Enabled = true;
                area.AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDot;
                area.AxisY.LabelAutoFitStyle = area.AxisY2.LabelAutoFitStyle = area.AxisX2.LabelAutoFitStyle =
                area.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.WordWrap | LabelAutoFitStyles.LabelsAngleStep90 | LabelAutoFitStyles.LabelsAngleStep45 | LabelAutoFitStyles.LabelsAngleStep30 | LabelAutoFitStyles.DecreaseFont;
                area.AxisY.Title = "请求访问量";
                area.AxisY.TextOrientation = TextOrientation.Stacked;

                area.AxisX.Title = "请求执行时间（单位：秒）";
                area.AxisX.TextOrientation = TextOrientation.Horizontal;

                area.Position.Y = 0;
                area.Position.X = 0;
                area.Position.Height = 50;
                area.Position.Width = 100;
                this.Inv(new Action(() =>
                {
                    this.chart1.ChartAreas.Add(area);
                }));
                this.ChageText("开始生成图表11111.。。。。。。area success---series");

                #endregion

                #region tubiao 1
                var s1 = new System.Windows.Forms.DataVisualization.Charting.Series("单位时间内top1")
                {
                    AxisLabel = "11_axisLab",
                    ChartArea = "s1",
                    BorderWidth = 1,
                };
                var s2 = new System.Windows.Forms.DataVisualization.Charting.Series("单位时间内top2")
                {
                    AxisLabel = "12_axisLab",
                    ChartArea = "s1",
                    BorderWidth = 1,
                };
                var s3 = new System.Windows.Forms.DataVisualization.Charting.Series("单位时间内top3")
                {
                    AxisLabel = "13_axisLab",
                    ChartArea = "s1",
                    BorderWidth = 1,
                };
                Dictionary<string, MyStruct> dic = new Dictionary<string, MyStruct>();
                //dic.Add("0", new MyStruct());
                //dic.Add("<1", logsEntity.Count(p => p.Timing < 1));
                this.ChageText("开始生成图表11111.。。。。。。。。1-2");
                dic.Add("1-2", logsEntity.Count(p => p.Timing > 1 && p.Timing <= 2));
                this.ChageText("开始生成图表11111.。。。。。。。。2-3");
                dic.Add("2-3", logsEntity.Count(p => p.Timing > 2 && p.Timing <= 3));
                this.ChageText("开始生成图表11111.。。。。。。。。3-4");
                dic.Add("3-4", logsEntity.Count(p => p.Timing > 3 && p.Timing <= 4));
                this.ChageText("开始生成图表11111.。。。。。。。。4-5");
                dic.Add("4-5", logsEntity.Count(p => p.Timing > 4 && p.Timing <= 5));
                dic.Add("5-6", logsEntity.Count(p => p.Timing > 5 && p.Timing <= 7));
                this.ChageText("开始生成图表11111.。。。。。。。。7-8");
                dic.Add("7-8", logsEntity.Count(p => p.Timing > 7 && p.Timing <= 9));
                dic.Add("9-10", logsEntity.Count(p => p.Timing > 9 && p.Timing <= 11));
                this.ChageText("开始生成图表11111.。。。。。。。。11-20");
                dic.Add("11-20", logsEntity.Count(p => p.Timing > 11 && p.Timing <= 21));
                this.ChageText("开始生成图表11111.。。。。。。。。21-50");
                dic.Add("21-50", logsEntity.Count(p => p.Timing > 21 && p.Timing <= 51));
                this.ChageText("开始生成图表11111.。。。。。。。。51-100");
                dic.Add("51-100", logsEntity.Count(p => p.Timing > 51 && p.Timing <= 101));
                this.ChageText("开始生成图表11111.。。。。。。。。>100");
                dic.Add(">100", logsEntity.Count(p => p.Timing > 100));
                this.ChageText("开始生成图表11111.。。。。。。。。foreach");

                #region foreach
                var x = 0d;
                foreach (var item in dic)
                {
                    this.ChageText("开始生成图表11111.。。。。。。。。foreach:" + item.Key);
                    ++x;
                    if (item.Value.Max1 > 0)

                        s1.Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint()
                        {
                            AxisLabel = item.Key,
                            Name = item.Key,
                            LegendText = item.Key,
                            IsValueShownAsLabel = true,
                            IsVisibleInLegend = true,
                            Label = item.Value.Max1Tip + Environment.NewLine + item.Value.Max1.ToString()
                            + "|" +
                            ((item.Value.Max1 /
                            page_count.FirstOrDefault(p => p.key == item.Value.Max1Tip).c) * 100).ToString("0.00") + "%",
                            YValues = new double[] { item.Value.Max1 },
                            XValue = x,
                        });
                    if (item.Value.Max2 > 0)
                        s2.Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint()
                        {
                            AxisLabel = item.Key,
                            Name = item.Key,
                            LegendText = item.Key,
                            IsValueShownAsLabel = true,
                            IsVisibleInLegend = true,
                            Label = item.Value.Max2Tip + Environment.NewLine + item.Value.Max2.ToString()
                            + "|" +
                            ((item.Value.Max2 /
                            page_count.FirstOrDefault(p => p.key == item.Value.Max2Tip).c) * 100).ToString("0.00") + "%",
                            YValues = new double[] { item.Value.Max2 },
                            XValue = x,
                            LabelAngle = 90

                        });
                    //if (item.Value.Max3 > 0)
                    //    s3.Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint()
                    //    {
                    //        AxisLabel = item.Key,
                    //        Name = item.Key,
                    //        LegendText = item.Key,
                    //        IsValueShownAsLabel = true,
                    //        IsVisibleInLegend = true,
                    //        Label = item.Value.Max3Tip + Environment.NewLine + item.Value.Max3.ToString()
                    //        //+ "。该类占比:" +
                    //        //((item.Value.Max3 /
                    //        //page_count.FirstOrDefault(p => p.key == item.Value.Max3Tip).c) * 100).ToString("0.00") + "%"
                    //        ,
                    //        YValues = new double[] { item.Value.Max3 },
                    //        XValue = x

                    //    });
                    //AddXY("<=1", logsEntity.Count(p => p.Timing <= 1));
                }
                //s1.Points[0].YValues = new double[] { page_count.FirstOrDefault().c / 30 };
                //s2.Points[0].YValues = new double[] { page_count.FirstOrDefault().c / 20 };
                //s3.Points[0].YValues = new double[] { page_count.FirstOrDefault().c / 10 };
                this.Inv(new Action(() =>
                {
                    this.chart1.Series.Add(s1);
                    this.chart1.Series.Add(s2);
                    //this.chart1.Series.Add(s3);
                }));
                #endregion
                #endregion


                this.ChageText("开始生成图表22222.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
                #region 222222222222222222

                var area2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea()
                {
                    Name = "s2",
                };
                area2.AxisY.MaximumAutoSize = 0.3F;
                area2.AxisX.Interval = 1;
                area2.AxisX.LineWidth = 1;
                area2.AxisY.LineWidth = 1;
                area2.AxisX.MajorGrid.Enabled = false;
                area2.AxisY.MajorGrid.Enabled = true;
                area2.AxisY.MajorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.DashDot;
                area2.AxisY.LabelAutoFitStyle = area2.AxisY2.LabelAutoFitStyle = area2.AxisX2.LabelAutoFitStyle =
                area2.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.WordWrap | LabelAutoFitStyles.LabelsAngleStep90 | LabelAutoFitStyles.LabelsAngleStep45 | LabelAutoFitStyles.LabelsAngleStep30 | LabelAutoFitStyles.DecreaseFont;
                area2.AxisY.Title = "请求访问量";
                area2.AxisY.TextOrientation = TextOrientation.Stacked;
                area2.AxisX.Title = "TOP3 请求执行时间（单位：秒）";
                area2.AxisX.TextOrientation = TextOrientation.Horizontal;
                area2.Position.X = 0;
                area2.Position.Y = 50;
                area2.Position.Height = 50;
                area2.Position.Width = 100;
                this.Inv(new Action(() =>
                {
                    this.chart1.ChartAreas.Add(area2);
                }));
                dic = new Dictionary<string, MyStruct>();
                //dic.Add("0", new MyStruct());
                this.ChageText("开始生成图表22222.。。。。。。。。。。1-3");
                dic.Add("1-3", logsEntity.Count(p => p.Timing > 1 && p.Timing <= 3));
                dic.Add("3-6", logsEntity.Count(p => p.Timing > 3 && p.Timing <= 6));
                this.ChageText("开始生成图表22222.。。。。。。。。。6-10");
                dic.Add("6-10", logsEntity.Count(p => p.Timing > 6 && p.Timing <= 10));
                dic.Add("10-50", logsEntity.Count(p => p.Timing > 10 && p.Timing <= 50));
                this.ChageText("开始生成图表22222.。。。。。。。。。。>50");
                dic.Add(">50", logsEntity.Count(p => p.Timing > 50));

                var ss1 = new System.Windows.Forms.DataVisualization.Charting.Series("2单位时间内top1")
                {
                    AxisLabel = "21_axisLab",
                    ChartArea = "s2",
                    BorderWidth = 1,
                };
                var ss2 = new System.Windows.Forms.DataVisualization.Charting.Series("2单位时间内top2")
                {
                    AxisLabel = "22_axisLab",
                    ChartArea = "s2",
                    BorderWidth = 1,
                };
                var ss3 = new System.Windows.Forms.DataVisualization.Charting.Series("2单位时间内top3")
                {
                    AxisLabel = "23_axisLab",
                    ChartArea = "s2",
                    BorderWidth = 1,
                };

                x = 0;
                this.ChageText("开始生成图表22222.。。。。。。。。。。。。。。foeach");

                #region foreach
                foreach (var item in dic)
                {
                    ++x;
                    this.ChageText("开始生成图表22222.。。。。。。。。。。。。。。foeach:" + item.Key);

                    if (item.Value.Max1 > 0)

                        ss1.Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint()
                        {
                            AxisLabel = item.Key,
                            Name = item.Key,
                            LegendText = item.Key,
                            IsValueShownAsLabel = true,
                            IsVisibleInLegend = true,
                            Label = item.Value.Max1Tip + Environment.NewLine + item.Value.Max1.ToString()
                            + "|" +
                            ((item.Value.Max1 /
                            page_count.FirstOrDefault(p => p.key == item.Value.Max1Tip).c) * 100).ToString("0.00") + "%",
                            YValues = new double[] { item.Value.Max1 },
                            XValue = x,
                        });
                    if (item.Value.Max2 > 0)
                        ss2.Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint()
                        {
                            AxisLabel = item.Key,
                            Name = item.Key,
                            LegendText = item.Key,
                            IsValueShownAsLabel = true,
                            IsVisibleInLegend = true,
                            Label = item.Value.Max2Tip + Environment.NewLine + item.Value.Max2.ToString()
                            + "|" +
                            ((item.Value.Max2 /
                            page_count.FirstOrDefault(p => p.key == item.Value.Max2Tip).c) * 100).ToString("0.00") + "%",
                            YValues = new double[] { item.Value.Max2 },
                            XValue = x,

                        });
                    if (item.Value.Max3 > 0)
                        ss3.Points.Add(new System.Windows.Forms.DataVisualization.Charting.DataPoint()
                        {
                            AxisLabel = item.Key,
                            Name = item.Key,
                            LegendText = item.Key,
                            IsValueShownAsLabel = true,
                            IsVisibleInLegend = true,
                            Label = item.Value.Max3Tip + Environment.NewLine + item.Value.Max3.ToString()
                                + "|" +
                                ((item.Value.Max3 /
                                page_count.FirstOrDefault(p => p.key == item.Value.Max3Tip).c) * 100).ToString("0.00") + "%"
                            ,
                            YValues = new double[] { item.Value.Max3 },
                            XValue = x

                        });
                }
                #endregion
                this.Inv(new Action(() =>
                {
                    this.chart1.Series.Add(ss1);
                    this.chart1.Series.Add(ss2);
                    this.chart1.Series.Add(ss3);
                }));
                #endregion

                var totalc = sw.ElapsedMilliseconds;
                sw.Stop();
                this.ChageText("完成。。。。。。。。。。。。。耗时：" + totalc);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
    [DebuggerDisplay("Max1={Max1},Max1Tip={Max1Tip}||Max2={Max2},Max2Tip={Max2Tip}||Max3={Max3},Max3Tip={Max3Tip}")]
    public struct MyStruct
    {
        public double Max1 { get; set; }
        public string Max1Tip { get; set; }

        public double Max2 { get; set; }
        public string Max2Tip { get; set; }

        public double Max3 { get; set; }
        public string Max3Tip { get; set; }
    }

    public static class Ext
    {
        public static MyStruct Count(this List<IGrouping<string, LogEntity>> source, Func<LogEntity, bool> func)
        {
            //source.ea(p => p.Where(func));
            //var list = source.Where(func);
            var lg =
                //list.GroupBy(p => p.PageName)
                 source
                .Select(p => new { Page = p.Key, Count = p.AsParallel().Count(func) })
                 .OrderByDescending(p => p.Count).Take(3).ToList();
            MyStruct my = new MyStruct();
            if (lg.Count > 0)
            {
                my.Max1 = lg[0].Count;
                my.Max1Tip = lg[0].Page;
            }
            if (lg.Count > 1)
            {
                my.Max2 = lg[1].Count;
                my.Max2Tip = lg[1].Page;
            }
            if (lg.Count > 2)
            {
                my.Max3 = lg[2].Count;
                my.Max3Tip = lg[2].Page;
            }
            return my;
        }

        public static int ToInt(this string source) {
            int o;
            return int.TryParse(source, out o) ? o : 0;
        }

        public static bool IsNullOrEmpty(this string source)
        {
            return String.IsNullOrEmpty(source);
        }
    }
}
